package com.jy.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jy.common.enums.ResponseWrapper;
import com.jy.common.model.dyamic.AiteUser;
import com.jy.common.model.dyamic.TopicParam;
import com.jy.common.model.user.param.TakeCardImageParam;
import com.jy.common.model.user.param.TakeCardReleaseParam;
import com.jy.common.tool.CommonTool;
import com.jy.common.tool.PositionChecker;
import com.jy.common.tool.ToolForDateTime;
import com.jy.entity.CardHistory;
import com.jy.entity.ThumbsUp;
import com.jy.entity.User;
import com.jy.entity.UserFollow;
import com.jy.mapper.CardHistoryMapper;
import com.jy.mapper.ThumbsUpMapper;
import com.jy.mapper.UserFollowMapper;
import com.jy.mapper.UserMapper;
import com.jy.service.CardHistoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

/**
 * <p>
 * 打卡记录表 服务实现类
 * </p>
 *
 * @author fzg
 * @since 2025-01-08
 */
@Service
public class CardHistoryServiceImpl extends ServiceImpl<CardHistoryMapper, CardHistory> implements CardHistoryService {

    private final CardHistoryMapper cardHistoryMapper;
    private final UserMapper userMapper;
    private final UserFollowMapper userFollowMapper;
    private final ThumbsUpMapper thumbsUpMapper;

    public CardHistoryServiceImpl(CardHistoryMapper cardHistoryMapper, UserMapper userMapper, UserFollowMapper userFollowMapper, ThumbsUpMapper thumbsUpMapper) {
        this.cardHistoryMapper = cardHistoryMapper;
        this.userMapper = userMapper;
        this.userFollowMapper = userFollowMapper;
        this.thumbsUpMapper = thumbsUpMapper;
    }

    @Override
    public ResponseWrapper takeCardRelease(HttpServletRequest request, TakeCardReleaseParam params) {

        // 返回结果
        HashMap<String, Object> result = new HashMap<>();

        long currentLoginUserAid = CommonTool.getUserAidByToken(request).longValue();

        CardHistory cardHistory = new CardHistory();
        cardHistory.setUserAid(currentLoginUserAid);
        cardHistory.setCardAddress(params.getCardAddress());
        cardHistory.setPosition(params.getPosition());
        cardHistory.setCardCity(params.getCardCity());

        // 积分要在以前没有打过卡的地方打卡之后才能获得，以前打过卡的地方周围20公里内再次打卡获取不了
        List<CardHistory> userTakeCardHistoryList = cardHistoryMapper.selectList(new LambdaQueryWrapper<CardHistory>()
                .eq(CardHistory::getUserAid, currentLoginUserAid)
        );
        List<String> positionList = new ArrayList<>();
        for (CardHistory history : userTakeCardHistoryList) {
            String position = history.getPosition();
            if (position!= null && !position.isEmpty()) {
                positionList.add(position);
            }
        }
        if(positionList.size() > 0){
            // 开始判断现在打卡这个地点是否在以前所有打过卡的方圆20公里内
            if(PositionChecker.isWithin20Kilometers(params.getPosition(),positionList)){
                // true就 +0 积分
                String[] lastNearCardHistory = PositionChecker.findNearestPositionWithin20Kilometers(params.getPosition(), positionList);
                assert lastNearCardHistory != null;
                List<CardHistory> cardHistories = cardHistoryMapper.selectList(new LambdaQueryWrapper<CardHistory>()
                        .eq(CardHistory::getUserAid, currentLoginUserAid)
                        .eq(CardHistory::getPosition, lastNearCardHistory[0])
                );
                if (cardHistories.size() > 0){
                    result.put("lastNearCardHistory",cardHistories.get(0));
                    result.put("distance",lastNearCardHistory[1]);
                }else {
                    result.put("lastNearCardHistory",null);
                    result.put("distance",null);
                }
                result.put("getRecords",0);
                cardHistory.setRecord(0);
            }else {
                cardHistory.setRecord(10);
                result.put("getRecords",10);
            }
        }else {
            // 说明这个用户还没有打过卡，还没有定位过，因此直接 +10 积分
            cardHistory.setRecord(10);
            result.put("getRecords",10);
        }
        cardHistory.setLikeNum(0L);
        cardHistory.setCommentNum(0L);
        cardHistory.setIsVideo(!params.getIsImage());
        cardHistory.setVedioUrl(params.getIsImage() ? null : params.getVideoUrl());
        if (params.getIsImage()){
            StringBuilder imgs = new StringBuilder();
            List<TakeCardImageParam> images = params.getImages();
            for (TakeCardImageParam image : images) {
                imgs.append(image.getImageUrl()).append(";");
            }
            // 去掉最后一个字符（即最后一个分号）
            if (imgs.length() > 0) {
                imgs.deleteCharAt(imgs.length() - 1);
            }
            System.out.println("图片：" +  imgs);
            cardHistory.setImageUrls(imgs.toString());
            cardHistory.setVideoCover(null);
        }else {
            cardHistory.setImageUrls(null);
            cardHistory.setVideoCover(params.getVideoCover());
        }
        cardHistory.setCopywritting(params.getCopywritting());
        // @的用户aid（字符串，用英文的分号隔开）
        List<AiteUser> aiteUsers = params.getAiteUsers();
        if (aiteUsers.size() > 0){
            StringBuilder str = new StringBuilder();
            for (AiteUser aiteUser : aiteUsers) {
                str.append(aiteUser.getUserAid()).append(";");
            }
            // 去掉最后一个字符（即最后一个分号）
            if (str.length() > 0) {
                str.deleteCharAt(str.length() - 1);
            }
            cardHistory.setAiteUsers(str.toString());
        }else {
            cardHistory.setAiteUsers(null);
        }

        // 话题（字符串，用英文的分号隔开）
        List<TopicParam> topicList = params.getTopicList();
        if (topicList.size() > 0){
            StringBuilder str = new StringBuilder();
            for (TopicParam topicParam : topicList) {
                str.append(topicParam.getTopicAid()).append(";");
            }
            // 去掉最后一个字符（即最后一个分号）
            if (str.length() > 0) {
                str.deleteCharAt(str.length() - 1);
            }
            cardHistory.setTopics(str.toString());
        }else {
            cardHistory.setTopics(null);
        }
        // 可见范围
        cardHistory.setSeeField(params.getSeeField());
        return cardHistoryMapper.insert(cardHistory) > 0 ? ResponseWrapper.markSuccess(result) : ResponseWrapper.markError();
    }

    @Override
    public ResponseWrapper getCardHistoryAllInfo(Integer currentLoginUserAid, Integer userAid) {

        // 返回结果
        HashMap<String, Object> result = new HashMap<>();

        User user = userMapper.selectById(userAid);
        // 用户背景
        result.put("userBg",(user.getBgImageUrl().equals("") || user.getBgImageUrl() == null) ? "https://wx2.sinaimg.cn/mw690/69c1dcbbgy1hsegdjms2sj20u00u0gqh.jpg" : user.getBgImageUrl());
        // 用户头像
        result.put("userAvatar",user.getAvatar());
        // 用户名
        result.put("userName",user.getName());

        List<CardHistory> cardHistories1 = cardHistoryMapper.selectList(new LambdaQueryWrapper<CardHistory>()
                .eq(CardHistory::getUserAid, userAid)
                .orderByDesc(CardHistory::getCreateTime)
        );

        // 打卡了多少个城市
        ArrayList<String> cardCitys = new ArrayList<>();
        if(cardHistories1.size() > 0){
            for (CardHistory cardHistory : cardHistories1) {
                if (!cardCitys.contains(cardHistory.getCardCity())){
                    cardCitys.add(cardHistory.getCardCity());
                }
            }
            result.put("cardCityNum", cardCitys.size());
        }else {
            result.put("cardCityNum", 0);
        }

        // 获得的总积分
        if(cardHistories1.size() > 0){
            Integer sumRecords = 0;
            Long sumLikeNums = 0L;
            ArrayList<HashMap<String,Object>> markers = new ArrayList<>();
            for (CardHistory cardHistory : cardHistories1) {
                sumRecords += cardHistory.getRecord();
                sumLikeNums += cardHistory.getLikeNum();
                HashMap<String, Object> marker = new HashMap<>();
                String position = cardHistory.getPosition();
                String[] split = position.split(",");
                marker.put("longitude",split[0]);
                marker.put("latitude",split[1]);
                marker.put("name",cardHistory.getCardAddress());
                markers.add(marker);
            }
            result.put("records",sumRecords);
            result.put("takeCardNum",cardHistories1.size());
            result.put("likeNum",sumLikeNums.intValue());
            result.put("markers",markers);
        }else {
            result.put("records",0);
            result.put("takeCardNum",0);
            result.put("likeNum",0);
            result.put("markers",new ArrayList<>());
        }

        // 当前登录的用户是否关注 userAid这个用户
        List<UserFollow> userFollows = userFollowMapper.selectList(new LambdaQueryWrapper<UserFollow>()
                .eq(UserFollow::getFollowerAid, currentLoginUserAid)
                .eq(UserFollow::getFolloweredAid, userAid)
                .eq(UserFollow::getFollowerType, "用户")
        );
        if (userFollows.size() > 0){
            result.put("guanzhuText","已关注");
        }else {
            result.put("guanzhuText","关注");
        }


        // 打卡记录列表
        ArrayList<HashMap<String, Object>> cardList = new ArrayList<>();
        if (cardHistories1.size() > 0){
            for (CardHistory cardHistory : cardHistories1) {
                HashMap<String, Object> card = new HashMap<>();
                card.put("cardAid",cardHistory.getAid());
                card.put("userAvatar",user.getAvatar());
                card.put("userName",user.getName());
                card.put("cardTime", ToolForDateTime.LocalDateTimeToStringToDate(cardHistory.getCreateTime()));
                card.put("cardAddress",cardHistory.getCardAddress());
                card.put("addRecord",cardHistory.getRecord());
                card.put("content",cardHistory.getCopywritting());
                ArrayList<String> imgs = getImgs(cardHistory);
                card.put("imgs",imgs);
                card.put("likeNum",cardHistory.getLikeNum());
                List<ThumbsUp> thumbsUps = thumbsUpMapper.selectList(new LambdaQueryWrapper<ThumbsUp>()
                        .eq(ThumbsUp::getThumbsUpUserAid, currentLoginUserAid)
                        .eq(ThumbsUp::getThumbsUpedAid, cardHistory.getAid())
                        .eq(ThumbsUp::getType, "旅行卡")
                );
                card.put("isLike", thumbsUps.size() > 0);
                card.put("commentNum", cardHistory.getCommentNum());
                cardList.add(card);
            }
            result.put("cardList",cardList);
        }else {
            result.put("cardList",new ArrayList<>());
        }
        return ResponseWrapper.markSuccess(result);
    }

    @Override
    public ResponseWrapper getAllRankInfo(Integer userAidByToken) {

        // 返回结果
        HashMap<String, Object> result = new HashMap<>();

        // 查询总榜
        List<Map<String, Object>> sumRecordByUserAidTotal = cardHistoryMapper.sumRecordByUserAid();
        System.out.println("每个人的旅行卡总积分" + JSONUtil.toJsonStr(sumRecordByUserAidTotal));
        rankRecords(sumRecordByUserAidTotal);
        System.out.println("现在每个人的旅行卡总积分" + JSONUtil.toJsonStr(sumRecordByUserAidTotal));
        for (Map<String, Object> stringObjectMap : sumRecordByUserAidTotal) {
            Object userAid = stringObjectMap.get("userAid");
            User user = userMapper.selectById(Long.valueOf(userAid.toString()));
            stringObjectMap.put("userAvatar",user.getAvatar());
            stringObjectMap.put("userName",user.getName());
            stringObjectMap.put("bg",user.getBgImageUrl());
        }
        System.out.println("总榜：" + JSONUtil.toJsonStr(sumRecordByUserAidTotal));
        result.put("AllrankList",sumRecordByUserAidTotal);

        // 我的总榜
        User user;
        HashMap<String, Object> myAllRank = null;
        for (Map<String, Object> stringObjectMap : sumRecordByUserAidTotal) {
            if (stringObjectMap.get("userAid").toString().equals(userAidByToken.toString())){
                user = userMapper.selectById(Long.valueOf(stringObjectMap.get("userAid").toString()));
                myAllRank = new HashMap<>();
                myAllRank.put("userAid",user.getAid());
                myAllRank.put("rank",stringObjectMap.get("rank"));
                myAllRank.put("userAvatar",user.getAvatar());
                myAllRank.put("userName",user.getName());
                myAllRank.put("records",stringObjectMap.get("records"));
                break; // 找到匹配项后退出循环
            }
        }
        if (myAllRank!=null){
            System.out.println("我排进了总榜" + JSONUtil.toJsonStr(myAllRank));
            result.put("myAllRank",myAllRank);
        }else {
            User user1 = userMapper.selectById(userAidByToken);
            List<CardHistory> cardHistories = cardHistoryMapper.selectList(new LambdaQueryWrapper<CardHistory>()
                    .eq(CardHistory::getUserAid, userAidByToken)
            );
            Integer myRrcodes = 0;
            myAllRank = new HashMap<>();
            myAllRank.put("userAid",user1.getAid());
            myAllRank.put("rank",sumRecordByUserAidTotal.size() + 1);
            myAllRank.put("userAvatar",user1.getAvatar());
            myAllRank.put("userName",user1.getName());
            for (CardHistory cardHistory : cardHistories) {
                myRrcodes += cardHistory.getRecord();
            }
            myAllRank.put("records",myRrcodes);
            System.out.println("我没进总榜" + JSONUtil.toJsonStr(myAllRank));
            result.put("myAllRank",myAllRank);
        }

        // 周榜
        List<CardHistory> cardHistories = cardHistoryMapper.selectList(null);
        List<CardHistory> lastWeekCardHistories = getLastWeekCardHistories(cardHistories);
        List<Map<String, Object>> lastWeekCardHistorieList = groupByUserAid(lastWeekCardHistories);
        rankRecords(lastWeekCardHistorieList);
        System.out.println("周榜：" + JSONUtil.toJsonStr(lastWeekCardHistorieList));
        for (Map<String, Object> stringObjectMap : lastWeekCardHistorieList) {
            Object userAid = stringObjectMap.get("userAid");
            User user1 = userMapper.selectById(Long.valueOf(userAid.toString()));
            stringObjectMap.put("userAvatar",user1.getAvatar());
            stringObjectMap.put("userName",user1.getName());
            stringObjectMap.put("bg",user1.getBgImageUrl());
        }
        System.out.println("现在的周榜：" + JSONUtil.toJsonStr(lastWeekCardHistorieList));
        result.put("weekRankList",lastWeekCardHistorieList);

        // 我的周榜排名
        User user2 = null;
        HashMap<String, Object> myRank = null;
        for (Map<String, Object> stringObjectMap : lastWeekCardHistorieList) {
            if (stringObjectMap.get("userAid").toString().equals(userAidByToken.toString())){
                user2 = userMapper.selectById(userAidByToken);
                myRank = new HashMap<>();
                myRank.put("userAid",user2.getAid());
                myRank.put("rank",stringObjectMap.get("rank"));
                myRank.put("userAvatar",user2.getAvatar());
                myRank.put("userName",user2.getName());
                myRank.put("records",stringObjectMap.get("records"));
                break; // 找到匹配项后退出循环
            }
        }
        if (myRank!=null){
            result.put("myRank",myRank);
        }else {
            User user1 = userMapper.selectById(userAidByToken);
            myRank = new HashMap<>();
            myRank.put("userAid",user1.getAid());
            myRank.put("rank",lastWeekCardHistorieList.size() + 1);
            myRank.put("userAvatar",user1.getAvatar());
            myRank.put("userName",user1.getName());
            myRank.put("records",0);
            result.put("myRank",myRank);
        }
        return ResponseWrapper.markSuccess(result);
    }

    public List<Map<String, Object>> groupByUserAid(List<CardHistory> cardHistories) {
        Map<Long, Integer> userAidToRecords = new HashMap<>();
        for (CardHistory cardHistory : cardHistories) {
            Long userAid = cardHistory.getUserAid();
            Integer record = cardHistory.getRecord();
            if (userAidToRecords.containsKey(userAid)) {
                userAidToRecords.put(userAid, userAidToRecords.get(userAid) + record);
            } else {
                userAidToRecords.put(userAid, record);
            }
        }

        List<Map<String, Object>> result = new ArrayList<>();
        for (Map.Entry<Long, Integer> entry : userAidToRecords.entrySet()) {
            Map<String, Object> item = new HashMap<>();
            item.put("userAid", entry.getKey());
            item.put("records", entry.getValue());
            result.add(item);
        }
        return result;
    }

    public static List<CardHistory> getLastWeekCardHistories(List<CardHistory> cardHistories) {

        LocalDateTime now = LocalDateTime.now();
        LocalDateTime lastMonday = LocalDateTime.of(now.minusWeeks(1).toLocalDate().with(DayOfWeek.MONDAY), LocalTime.MIN);
        LocalDateTime lastSunday = LocalDateTime.of(now.minusWeeks(1).toLocalDate().with(DayOfWeek.SUNDAY), LocalTime.MAX);
        List<CardHistory> lastWeekCardHistories = new ArrayList<>();
        for (CardHistory cardHistory : cardHistories) {
            LocalDateTime createTime = cardHistory.getCreateTime();
            if (createTime.isAfter(lastMonday) && createTime.isBefore(lastSunday)) {
                lastWeekCardHistories.add(cardHistory);
            }
        }
        return lastWeekCardHistories;
    }

    public static void rankRecords(List<Map<String, Object>> records) {
        // 自定义排序规则，按照 totalRecord 降序排序
        records.sort((o1, o2) -> {
            // 获取 records 对应的值，并处理类型转换
            Object record1 = o1.get("records");
            Object record2 = o2.get("records");
            BigDecimal totalRecord1;
            BigDecimal totalRecord2;
            if (record1 instanceof BigDecimal) {
                totalRecord1 = (BigDecimal) record1;
            } else if (record1 instanceof Integer) {
                totalRecord1 = BigDecimal.valueOf((Integer) record1);
            } else {
                // 可以根据需要处理其他类型，这里假设其他类型默认为 0
                totalRecord1 = BigDecimal.ZERO;
            }
            if (record2 instanceof BigDecimal) {
                totalRecord2 = (BigDecimal) record2;
            } else if (record2 instanceof Integer) {
                totalRecord2 = BigDecimal.valueOf((Integer) record2);
            } else {
                // 可以根据需要处理其他类型，这里假设其他类型默认为 0
                totalRecord2 = BigDecimal.ZERO;
            }
            // 比较两个 BigDecimal 的大小，实现降序排序
            return totalRecord2.compareTo(totalRecord1);
        });

        int rank = 1;
        BigDecimal prevTotalRecord = BigDecimal.valueOf(Long.MAX_VALUE);
        int sameRankCount = 0;
        for (Map<String, Object> record : records) {
            BigDecimal totalRecord;
            Object value = record.get("records");
            if (value instanceof BigDecimal) {
                totalRecord = (BigDecimal) value;
            } else if (value instanceof Integer) {
                totalRecord = BigDecimal.valueOf((Integer) value);
            } else {
                // 可以根据需要处理其他类型，这里假设其他类型默认为 0
                totalRecord = BigDecimal.ZERO;
            }
            if (totalRecord.compareTo(prevTotalRecord) < 0) {
                rank += sameRankCount;
                sameRankCount = 0;
            }
            record.put("rank", rank);
            prevTotalRecord = totalRecord;
            sameRankCount++;
        }
    }


    private static ArrayList<String> getImgs(CardHistory cardHistory) {
        Boolean isVideo = cardHistory.getIsVideo();
        ArrayList<String> imgs = new ArrayList<>();
        if (isVideo){
            imgs.add(cardHistory.getVideoCover());
        }else {
            String imageUrls = cardHistory.getImageUrls();
            if (imageUrls.contains(";")){
                String[] split = imageUrls.split(";");
                List<String> imgurlList = Arrays.asList(split);
                imgs.addAll(imgurlList);
            }else {
                imgs.add(imageUrls);
            }
        }
        return imgs;
    }
}
